package main

import (
	"bytes"
	"crypto/sha1"
	"crypto/tls"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/patrickmn/go-cache"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"time"
)

var goCache *cache.Cache  //定义全局变量
func init(){
	goCache = cache.New(5*time.Minute, 60*time.Second)
}
const ApiHost = "ip:port"
const TipHost = "domain"
const AppId = "id"
const AppKey = "key"

type TokenStruct struct {
	AccessToken         string   	`json:"access_token"`
	ExpiresIn           int      	`json:"expires_in"`
	Status              int      	`json:"status"`
	Message             string      `json:"message"`
	Fingerprint         string      `json:"fingerprint"`
}

var simpleHostProxy = httputil.ReverseProxy{
	Director: func(req *http.Request) {
		req.URL.Scheme = "https"
		req.URL.Host = ApiHost
		req.Host = TipHost
	},
}

func main() {

	//fmt.Println("jsonStr", GetToken())
	engine := gin.New()
	vi := engine.Group("/pawn")
	vi.Any("/*action", WithHeader)
	err := engine.Run(":8080")
	if err != nil {
		fmt.Println(err)
	}
}

/**
设置代理后的header
 */
func WithHeader(ctx *gin.Context) {
	var accessToken string
	tokenCache, err := goCache.Get("access_token_ddh")
	if err == false{
		accessToken = GetToken().AccessToken
	} else {
		accessToken = tokenCache.(string)
		fmt.Println("已缓存Token",tokenCache)
	}
	ctx.Request.Header.Add("X-trustagw-access-token", accessToken)
	ctx.Request.Header.Add("host", TipHost)
	http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
	simpleHostProxy.ServeHTTP(ctx.Writer, ctx.Request)
}

/**
获取token
 */
func GetToken() TokenStruct {

	song := make(map[string]interface{})
	song["app_id"] = AppId
	song["fingerprint"] = GetFingerprint()
	config := JsonPost(song)
	goCache.Set("access_token_ddh", config.AccessToken, 40*time.Minute)

	return config
}

/**
获取tip指纹
 */
func GetFingerprint() string {
	sha1Str := "app_id="+AppId+"&app_key="+AppKey

	fmt.Println("sha1Str", sha1Str)
	h := sha1.New()
	//写入要处理的字节。如果是一个字符串，需要使用[]byte(s) 来强制转换成字节数组。
	h.Write([]byte(sha1Str))
	return base64.StdEncoding.EncodeToString(h.Sum([]byte("")))
}
/**
post请求
 */
func JsonPost(song map[string]interface{}) TokenStruct  {
	jsonStr, err := json.Marshal(song)
	fmt.Println("jsonStr", jsonStr)
	fmt.Println("new_str", bytes.NewBuffer(jsonStr))


	req, err := http.NewRequest("POST", "https://"+ApiHost+"/sts/token", bytes.NewBuffer(jsonStr))
	// req.Header.Set("X-Custom-Header", "myvalue")
	req.Header.Set("Content-Type", "application/json")

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	//client := &http.Client{}
	client := &http.Client{Transport: tr}
	resp, err := client.Do(req)
	if err != nil{
		panic(err)
	}
	defer resp.Body.Close()

	fmt.Println("status", resp.Status)
	fmt.Println("response:", resp.Header)
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println("response Body:", string(body))


	var configStruct TokenStruct
	if err := json.Unmarshal(body, &configStruct); err == nil {
		return configStruct
	}


	return configStruct
}
